#include "SimpleImage.h"
#include "simpleimageluabindings.h"
#include "../core/LuaUtils.h"

RegisterCustomDatatype<SimpleImageLuaBindings> g_simpleimage_dt("SimpleImage");

int donothingspecial_simpimg()
{
	return 16;
}

void SimpleImageLuaBindings::registerFunctions(lua_State* L)
{
	SimpleImageLuaBindings::pushStaticFuncs(L);
}

void SimpleImageLuaBindings::pushStaticFuncs(lua_State* L)
{
	static const struct luaL_Reg mylib [] = {
		{"AllocateLayered", li_allocateLayered},
		{"AllocateInterleaved", li_allocateInterleaved},
		{"Deallocate", li_deallocate},
		{"Untether", li_untether},
		{"Clone", li_clone},
		{"RawGet", li_rawGet},
		{"Get", li_get},
		{"RawSet", li_rawSet},
		{"Set", li_set},
		{"RawPos", li_rawPos},
		{"__gc", li_deleteThis},
		{"SizeX", li_sizeX},
		{"SizeY", li_sizeY},
		{"SizeC", li_sizeC},
		{"Size", li_size},
		{"Getmx", li_getmx},
		{"Getmy", li_getmy},
		{"Getmc", li_getmc},
		{"Getb", li_getb},
		{"FromString", li_fromString},
		{"ToString", li_toString},
		{"DeepCopy", li_deepCopy},
		{"GetBounds", li_getBounds},
		{NULL, NULL}  /* sentinel */
	};

	// dump them into said table
	luaL_register(L, NULL, mylib);
}

int SimpleImageLuaBindings::li_allocateLayered(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	int a2 = (int)lua_tointeger(L, 3);
	int a3 = (int)lua_tointeger(L, 4);
	op->allocateLayered(a1, a2, a3);
	
	return 0;
}


int SimpleImageLuaBindings::li_allocateInterleaved(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	int a2 = (int)lua_tointeger(L, 3);
	int a3 = (int)lua_tointeger(L, 4);
	op->allocateInterleaved(a1, a2, a3);
	
	return 0;
}


int SimpleImageLuaBindings::li_deallocate(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	op->deallocate();
	
	return 0;
}

int SimpleImageLuaBindings::li_untether(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	op->untether();

	return 0;
}

int SimpleImageLuaBindings::li_clone(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}

	SimpleImage ret = op->clone();
	push_custom<SimpleImage>(L, &ret, "SimpleImage");

	return 1;
}


int SimpleImageLuaBindings::li_rawGet(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	UCHAR ret = op->rawGet(a1);
	lua_pushnumber(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_get(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	int a2 = (int)lua_tointeger(L, 3);
	int a3 = (int)lua_tointeger(L, 4);
	UCHAR ret = op->get(a1, a2, a3);
	lua_pushnumber(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_rawSet(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	UCHAR a2 = (UCHAR)lua_tonumber(L, 3);
	op->rawSet(a1, a2);
	
	return 0;
}


int SimpleImageLuaBindings::li_set(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	int a2 = (int)lua_tointeger(L, 3);
	int a3 = (int)lua_tointeger(L, 4);
	UCHAR a4 = (UCHAR)lua_tonumber(L, 5);
	op->set(a1, a2, a3, a4);
	
	return 0;
}


int SimpleImageLuaBindings::li_rawPos(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	int a2 = (int)lua_tointeger(L, 3);
	int a3 = (int)lua_tointeger(L, 4);
	int ret = op->rawPos(a1, a2, a3);
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_deleteThis(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	op->deleteThis();
	
	return 0;
}


int SimpleImageLuaBindings::li_sizeX(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->sizeX();
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_sizeY(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->sizeY();
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_sizeC(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->sizeC();
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_size(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->size();
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_getmx(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->getmx();
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_getmy(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->getmy();
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_getmc(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->getmc();
	lua_pushinteger(L, ret);
	return 1;
}


int SimpleImageLuaBindings::li_getb(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int ret = op->getb();
	lua_pushinteger(L, ret);
	return 1;
}

int SimpleImageLuaBindings::li_fromString(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
		return 0;
	}
	size_t tempi;
	const char* tempcp = lua_tolstring(L, 2, &tempi);
	op->fromBytes((unsigned char*)tempcp, tempi);
	return 0;
	//temps = std::string(tempcp, tempi);
}

int SimpleImageLuaBindings::li_toString(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	std::string tempstr = op->toStdString();
	lua_pushlstring(L, tempstr.data(), tempstr.length());
	return 1;
}

int SimpleImageLuaBindings::li_deepCopy(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	SimpleImage* a1 = pop_custom<SimpleImage>(L, 2, "SimpleImage");
	if(a1 == NULL)
	{
		LOG(logERROR) << "Null deep copy source!";
		return 0;
	}
	op->deepCopy(*a1);
	return 0;
}

int SimpleImageLuaBindings::li_getBounds(lua_State* L)
{
	SimpleImage* op = pop_custom<SimpleImage>(L, 1, "SimpleImage");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	UCHAR thresh = (UCHAR)lua_tointeger(L, 2);
	int chan = lua_tointeger(L, 3);
	int x1 = 0;
	int y1 = 0;
	int w = 0;
	int h = 0;
	op->getBounds(x1, y1, w, h, thresh, chan);
	lua_pushnumber(L, x1);
	lua_pushnumber(L, y1);
	lua_pushnumber(L, w);
	lua_pushnumber(L, h);
	return 4;
}


